const express = require('express');
const router = express.Router();

const UserPrisma = require('../models/UserPrisma');
const InvitationPrisma = require('../models/InvitationPrisma');
const wechatAPI = require('../utils/wechat');
const { generateToken } = require('../middleware/auth');
const ResponseHelper = require('../utils/response');
const UserLocationHelper = require('../utils/userLocation');
const unionBindingService = require('../services/unionBinding');

/**
 * 接口 1: 微信静默登录
 * POST /api/v1/auth/login
 * 
 * 输入: 小程序端通过 wx.login() 获取的 code
 * 逻辑: 调用微信官方 code2Session 接口，用 code 换取用户的 openid 和 session_key
 * 数据库: 根据 openid 查询 users 表。若用户不存在，则创建新用户；若存在，则更新最后登录时间
 * 输出: 生成 JWT，将 user_id, openid 等信息加密后返回给小程序端
 */
router.post('/login', async (req, res) => {
  try {
    const { code, inviterId, userProfile } = req.body;

    // 验证必填参数
    if (!code) {
      return ResponseHelper.validationError(res, ['code 是必填参数']);
    }

    console.log('登录请求参数:', { code, inviterId, userProfile });

    const requestLocation = await UserLocationHelper.resolveLocationFromRequest(req);

    // 调用微信接口获取用户信息
    let wechatData;
    try {
      wechatData = await wechatAPI.code2Session(code);
    } catch (error) {
      console.error('微信登录失败:', error);
      return ResponseHelper.error(res, '微信登录失败，请重试', 400);
    }

    const { openid, session_key, unionid } = wechatData;
    const unionId = unionid || null;
    console.log('微信登录成功，openid:', openid, 'unionId:', unionId);

    // 查找或创建用户（支持 unionId 关联）
    let user = await unionBindingService.findUserByIdentifiers({ openid, unionId });

    if (user) {
      // 用户已存在，更新最后登录时间和用户信息（如果提供了新的用户信息）
      await UserPrisma.updateLastLogin(user.id);

      // 如果提供了用户信息，更新用户资料
      if (userProfile) {
        const updateData = {};
        if (userProfile.nickname && userProfile.nickname !== user.nickname) {
          updateData.nickname = userProfile.nickname;
        }
        if (userProfile.avatar_url && userProfile.avatar_url !== user.avatar_url) {
          updateData.avatar_url = userProfile.avatar_url;
        }

        // 如果有需要更新的数据，执行更新
        if (Object.keys(updateData).length > 0) {
          console.log('更新用户信息:', updateData);
          user = await UserPrisma.update(user.id, updateData);
        }
      }

      user = await UserLocationHelper.maybeUpdateUserLocation(user, requestLocation);
    } else {
      // 新用户，创建账户
      const userData = {
        openid,
        union_id: unionId,
        status: 'inactive',
        publishing_credits: 0
      };

      const locationPayload = UserLocationHelper.buildLocationPayload(requestLocation);
      if (locationPayload) {
        Object.assign(userData, locationPayload);
      }

      // 如果提供了用户信息，添加到用户数据中
      if (userProfile) {
        if (userProfile.nickname) userData.nickname = userProfile.nickname;
        if (userProfile.avatar_url) userData.avatar_url = userProfile.avatar_url;
        console.log('创建新用户，包含用户信息:', userData);
      }

      // 如果有邀请者ID，设置邀请关系
      if (inviterId) {
        const inviter = await UserPrisma.findById(inviterId);
        if (inviter) {
          userData.inviter_id = inviterId;
        }
      }

      user = await UserPrisma.create(userData);

      // 如果有邀请者，创建邀请记录并处理激活逻辑
      if (inviterId && userData.inviter_id) {
        try {
          // 创建邀请记录
          await InvitationPrisma.create({
            inviter_user_id: inviterId,
            invitee_user_id: user.id,
            reward_type: 'activation',
            reward_value: 1,
            status: 'unclaimed'
          });

          // 处理邀请奖励和激活逻辑
          const { activated, rewardGiven } = await InvitationPrisma.processInvitationReward(inviterId);

          console.log(`邀请处理结果: 邀请者${inviterId}, 激活状态: ${activated}, 奖励发放: ${rewardGiven}`);
        } catch (error) {
          console.error('处理邀请逻辑失败:', error);
          // 不影响用户注册流程，只记录错误
        }
      }
    }

    // 确保 openid / unionId 已落库
    user = await unionBindingService.ensureOpenPlatformBinding(user, { openid, unionId });

    user = await UserLocationHelper.maybeUpdateUserLocation(user, requestLocation);

    // 生成JWT token
    const token = generateToken({
      user_id: user.id.toString(), // BigInt转字符串
      openid: user.openid
    });

    // 返回登录成功信息
    ResponseHelper.success(res, {
      token,
      user: user.toJSON(),
      isNewUser: !user.created_at || new Date() - new Date(user.created_at) < 60000 // 1分钟内创建的算新用户
    }, '登录成功');

  } catch (error) {
    console.error('登录接口错误:', error);
    ResponseHelper.serverError(res, '登录失败', error);
  }
});

/**
 * 刷新token接口
 * POST /api/v1/auth/refresh
 */
router.post('/refresh', async (req, res) => {
  try {
    const { token } = req.body;

    if (!token) {
      return ResponseHelper.validationError(res, ['token 是必填参数']);
    }

    // 验证旧token（即使过期也要能解析）
    const jwt = require('jsonwebtoken');
    let decoded;
    try {
      decoded = jwt.verify(token, process.env.JWT_SECRET);
    } catch (error) {
      if (error.name === 'TokenExpiredError') {
        // token过期，尝试解析
        decoded = jwt.decode(token);
      } else {
        return ResponseHelper.unauthorized(res, '无效的token');
      }
    }

    if (!decoded || !decoded.user_id) {
      return ResponseHelper.unauthorized(res, '无效的token');
    }

    // 查找用户
    const user = await UserPrisma.findById(decoded.user_id);
    if (!user) {
      return ResponseHelper.unauthorized(res, '用户不存在');
    }

    // 生成新token
    const newToken = generateToken({
      user_id: user.id.toString(), // BigInt转字符串
      openid: user.openid
    });

    ResponseHelper.success(res, {
      token: newToken,
      user: user.toJSON()
    }, 'Token刷新成功');

  } catch (error) {
    console.error('刷新token错误:', error);
    ResponseHelper.serverError(res, 'Token刷新失败', error);
  }
});

/**
 * 手机号快捷登录接口
 * POST /api/v1/auth/phone-login
 *
 * 输入: 小程序端通过 wx.login() 获取的 code 和通过 getPhoneNumber 获取的 phoneCode
 * 逻辑: 调用微信官方接口获取 openid 和手机号，根据手机号查询或创建用户
 * 输出: 生成 JWT，将 user_id, openid 等信息加密后返回给小程序端
 */
router.post('/phone-login', async (req, res) => {
  try {
    const { code, phoneCode, inviterId, userProfile } = req.body;

    // 验证必填参数
    if (!code || !phoneCode) {
      return ResponseHelper.validationError(res, ['code 和 phoneCode 是必填参数']);
    }

    console.log('手机号登录请求参数:', { code, phoneCode, inviterId, userProfile });

    const requestLocation = await UserLocationHelper.resolveLocationFromRequest(req);

    // 调用微信接口获取用户openid
    let wechatData;
    try {
      wechatData = await wechatAPI.code2Session(code);
    } catch (error) {
      console.error('微信登录失败:', error);
      return ResponseHelper.error(res, '微信登录失败，请重试', 400);
    }

    const { openid, session_key } = wechatData;
    console.log('微信登录成功，openid:', openid);

    // 调用微信接口获取手机号
    let phoneData;
    try {
      phoneData = await wechatAPI.getPhoneNumber(phoneCode, openid);
    } catch (error) {
      console.error('获取手机号失败:', error);

      // 如果是权限问题，提供更友好的错误信息
      if (error.message.includes('HTTP 412') || error.message.includes('48001')) {
        return ResponseHelper.error(res, '小程序暂未获得获取手机号权限，请使用手动输入手机号登录', 403);
      }

      return ResponseHelper.error(res, '获取手机号失败，请重试', 400);
    }

    const phoneNumber = phoneData.purePhoneNumber;
    console.log('获取手机号成功:', phoneNumber);

    // 查找或创建用户
    let user = await UserPrisma.findByOpenid(openid);

    if (user) {
      // 用户已存在，更新最后登录时间和手机号（如果没有的话）
      await UserPrisma.updateLastLogin(user.id);

      // 更新用户信息
      const updateData = {};
      if (!user.phone_number && phoneNumber) {
        updateData.phone_number = phoneNumber;
      }
      if (userProfile) {
        if (userProfile.nickname && userProfile.nickname !== user.nickname) {
          updateData.nickname = userProfile.nickname;
        }
        if (userProfile.avatar_url && userProfile.avatar_url !== user.avatar_url) {
          updateData.avatar_url = userProfile.avatar_url;
        }
      }

      // 如果有需要更新的数据，执行更新
      if (Object.keys(updateData).length > 0) {
        console.log('更新用户信息:', updateData);
        user = await UserPrisma.update(user.id, updateData);
      }

      user = await UserLocationHelper.maybeUpdateUserLocation(user, requestLocation);
    } else {
      // 新用户，创建账户
      const userData = {
        openid,
        phone_number: phoneNumber,
        status: 'inactive',
        publishing_credits: 0
      };

      const locationPayload = UserLocationHelper.buildLocationPayload(requestLocation);
      if (locationPayload) {
        Object.assign(userData, locationPayload);
      }

      // 添加用户信息
      if (userProfile) {
        if (userProfile.nickname) userData.nickname = userProfile.nickname;
        if (userProfile.avatar_url) userData.avatar_url = userProfile.avatar_url;
      }

      // 处理邀请逻辑
      if (inviterId) {
        const inviter = await UserPrisma.findById(inviterId);
        if (inviter) {
          userData.inviter_id = inviterId;
        }
      }

      user = await UserPrisma.create(userData);

      // 如果有邀请者，创建邀请记录并处理激活逻辑
      if (inviterId && userData.inviter_id) {
        try {
          // 创建邀请记录
          await InvitationPrisma.create({
            inviter_user_id: inviterId,
            invitee_user_id: user.id,
            reward_type: 'activation',
            reward_value: 1,
            status: 'unclaimed'
          });

          // 处理邀请奖励和激活逻辑
          const { activated, rewardGiven } = await InvitationPrisma.processInvitationReward(inviterId);

          console.log(`邀请处理结果: 邀请者${inviterId}, 激活状态: ${activated}, 奖励发放: ${rewardGiven}`);
        } catch (error) {
          console.error('处理邀请逻辑失败:', error);
          // 不影响用户注册流程，只记录错误
        }
      }
    }

    user = await UserLocationHelper.maybeUpdateUserLocation(user, requestLocation);

    // 生成JWT token
    const token = generateToken({
      user_id: user.id.toString(), // BigInt转字符串
      openid: user.openid
    });

    ResponseHelper.success(res, {
      token,
      user: user.toJSON()
    }, '手机号登录成功');

  } catch (error) {
    console.error('手机号登录错误:', error);
    ResponseHelper.serverError(res, '手机号登录失败', error);
  }
});

/**
 * 获取手机号接口（供前端调用）
 * POST /api/v1/auth/get-phone-number
 *
 * 输入: 手机号授权code
 * 输出: 解密后的手机号信息
 * 安全: AppSecret在后端，不暴露给前端
 */
router.post('/get-phone-number', async (req, res) => {
  try {
    const { code } = req.body;

    // 验证必填参数
    if (!code) {
      return ResponseHelper.validationError(res, ['code 是必填参数']);
    }

    console.log('获取手机号请求:', { code });

    // 调用微信接口获取手机号
    let phoneData;
    try {
      phoneData = await wechatAPI.getPhoneNumber(code);
    } catch (error) {
      console.error('获取手机号失败:', error);

      if (error.message.includes('HTTP 412') || error.message.includes('48001')) {
        return ResponseHelper.error(res, '小程序暂未获得获取手机号权限', 403);
      }

      return ResponseHelper.error(res, '获取手机号失败，请重试', 400);
    }

    ResponseHelper.success(res, {
      phoneNumber: phoneData.phoneNumber,
      purePhoneNumber: phoneData.purePhoneNumber,
      countryCode: phoneData.countryCode
    }, '获取手机号成功');

  } catch (error) {
    console.error('获取手机号错误:', error);
    ResponseHelper.serverError(res, '获取手机号失败', error);
  }
});

/**
 * 手机号登录接口（手动输入）
 * POST /api/v1/auth/manual-phone-login
 *
 * 输入: 小程序端通过 wx.login() 获取的 code 和用户手动输入的手机号
 * 逻辑: 调用微信官方接口获取 openid，使用手动输入的手机号创建或查询用户
 * 输出: 生成 JWT，将 user_id, openid 等信息加密后返回给小程序端
 */
router.post('/manual-phone-login', async (req, res) => {
  try {
    const { code, phoneNumber, inviterId, userProfile } = req.body;

    // 验证必填参数
    if (!code || !phoneNumber) {
      return ResponseHelper.validationError(res, ['code 和 phoneNumber 是必填参数']);
    }

    // 验证手机号格式
    if (!/^1[3-9]\d{9}$/.test(phoneNumber)) {
      return ResponseHelper.validationError(res, ['手机号格式不正确']);
    }

    console.log('手机号登录请求参数:', { code, phoneNumber, inviterId, userProfile });

    const requestLocation = await UserLocationHelper.resolveLocationFromRequest(req);

    // 调用微信接口获取用户openid
    let wechatData;
    try {
      wechatData = await wechatAPI.code2Session(code);
    } catch (error) {
      console.error('微信登录失败:', error);

      // 开发环境下，如果是测试code，使用模拟数据
      if (process.env.NODE_ENV === 'development' && code.startsWith('test_')) {
        console.log('🧪 开发模式：使用模拟微信数据');
        wechatData = {
          openid: 'test_openid_' + Date.now(),
          session_key: 'test_session_key'
        };
      } else {
        return ResponseHelper.error(res, '微信登录失败，请重试', 400);
      }
    }

    const { openid, session_key } = wechatData;
    console.log('微信登录成功，openid:', openid);
    console.log('使用手动输入的手机号:', phoneNumber);

    // 查找或创建用户
    let user = await UserPrisma.findByOpenid(openid);

    if (user) {
      // 用户已存在，更新最后登录时间和手机号（如果没有的话）
      await UserPrisma.updateLastLogin(user.id);

      // 更新用户信息
      const updateData = {};
      if (!user.phone_number && phoneNumber) {
        updateData.phone_number = phoneNumber;
      }
      if (userProfile) {
        if (userProfile.nickname && userProfile.nickname !== user.nickname) {
          updateData.nickname = userProfile.nickname;
        }
        if (userProfile.avatar_url && userProfile.avatar_url !== user.avatar_url) {
          updateData.avatar_url = userProfile.avatar_url;
        }
      }

      // 如果有需要更新的数据，执行更新
      if (Object.keys(updateData).length > 0) {
        console.log('更新用户信息:', updateData);
        user = await UserPrisma.update(user.id, updateData);
      }

      user = await UserLocationHelper.maybeUpdateUserLocation(user, requestLocation);
    } else {
      // 新用户，创建账户
      const userData = {
        openid,
        phone_number: phoneNumber,
        status: 'inactive',
        publishing_credits: 0
      };

      const locationPayload = UserLocationHelper.buildLocationPayload(requestLocation);
      if (locationPayload) {
        Object.assign(userData, locationPayload);
      }

      // 添加用户信息
      if (userProfile) {
        if (userProfile.nickname) userData.nickname = userProfile.nickname;
        if (userProfile.avatar_url) userData.avatar_url = userProfile.avatar_url;
      }

      // 处理邀请逻辑
      if (inviterId) {
        const inviter = await UserPrisma.findById(inviterId);
        if (inviter) {
          userData.inviter_id = inviterId;
        }
      }

      user = await UserPrisma.create(userData);

      // 如果有邀请者，创建邀请记录并处理激活逻辑
      if (inviterId && userData.inviter_id) {
        try {
          // 创建邀请记录
          await InvitationPrisma.create({
            inviter_user_id: inviterId,
            invitee_user_id: user.id,
            reward_type: 'activation',
            reward_value: 1,
            status: 'unclaimed'
          });

          // 处理邀请奖励和激活逻辑
          const { activated, rewardGiven } = await InvitationPrisma.processInvitationReward(inviterId);

          console.log(`邀请处理结果: 邀请者${inviterId}, 激活状态: ${activated}, 奖励发放: ${rewardGiven}`);
        } catch (error) {
          console.error('处理邀请逻辑失败:', error);
          // 不影响用户注册流程，只记录错误
        }
      }
    }

    user = await UserLocationHelper.maybeUpdateUserLocation(user, requestLocation);

    // 生成JWT token
    const token = generateToken({
      user_id: user.id.toString(), // BigInt转字符串
      openid: user.openid
    });

    ResponseHelper.success(res, {
      token,
      user: user.toJSON()
    }, '手机号登录成功');

  } catch (error) {
    console.error('手机号登录错误:', error);
    ResponseHelper.serverError(res, '手机号登录失败', error);
  }
});

/**
 * 测试登录接口
 * POST /api/v1/auth/test-login
 *
 * 用于开发测试，绕过微信登录验证，直接使用测试用户登录
 * 注意：此接口仅用于开发环境，生产环境应禁用
 */
router.post('/test-login', async (req, res) => {
  try {
    // 检查是否为开发环境
    if (process.env.NODE_ENV === 'production') {
      return ResponseHelper.error(res, '测试登录接口在生产环境中不可用', 403);
    }

    console.log('🧪 使用测试登录接口');

    // 查找测试用户
    const testOpenid = 'test_user_main_001';
    let user = await UserPrisma.findByOpenid(testOpenid);

    if (!user) {
      return ResponseHelper.error(res, '测试用户不存在，请先运行创建测试用户脚本', 404);
    }

    // 更新最后登录时间
    await UserPrisma.updateLastLogin(user.id);

    // 生成JWT token
    const token = generateToken({
      user_id: user.id.toString(), // BigInt转字符串
      openid: user.openid
    });

    // 返回登录成功信息
    ResponseHelper.success(res, {
      token,
      user: user.toJSON(),
      isNewUser: false,
      isTestUser: true // 标识这是测试用户
    }, '测试登录成功');

    console.log(`✅ 测试用户登录成功: ${user.nickname} (ID: ${user.id})`);

  } catch (error) {
    console.error('测试登录接口错误:', error);
    ResponseHelper.serverError(res, '测试登录失败', error);
  }
});

/**
 * 登出接口
 * POST /api/v1/auth/logout
 */
router.post('/logout', (req, res) => {
  // JWT是无状态的，客户端删除token即可
  ResponseHelper.success(res, null, '登出成功');
});

module.exports = router;
